#include "Sensor_Data_Handler.h"

#pragma MESSAGE DISABLE C4001

uint16 u16adc_x_10bit_max;		//Max value allowed in 10 bit
uint16 u16adc_y_10bit_max;
uint16 u16adc_z_10bit_max;

uint16 u16adc_x_10bit_min;
uint16 u16adc_y_10bit_min;
uint16 u16adc_z_10bit_min;

extern const uint16 u16_ADCX_10b_zero_offset;
extern const uint16 u16_ADCY_10b_zero_offset;
extern const uint16 u16_ADCZ_10b_zero_offset;

extern uint8 u8FreeFall;

int8 i8adc_xoffset_calibration;	//Real offset. This value is substracted from ADC measure
int8 i8adc_yoffset_calibration;
int8 i8adc_zoffset_calibration;

uint8 u8Sensor_TestAccel(void)
{
	uint16 tempo;
	uint16 u16x0;
	
	ACCEL_SELF_TEST_DD = GPIO_OUTPUT;
	ACCEL_SELF_TEST = ACCEL_NORMAL_OPERATION;
	
	mDELAY_TEST_ACCEL;	
	
	vfnADC_ChannelSelect (SENSOR_ACCEL_Z_CH);
    while(!u8ADC_CheckCCF());
        					 
    u16x0 = u16ADC_GetResult();
    
    ACCEL_SELF_TEST = ACCEL_SELF_TEST_MODE;
	
	mDELAY_TEST_ACCEL;	
	
	vfnADC_ChannelSelect (SENSOR_ACCEL_Z_CH);
    while(!u8ADC_CheckCCF());
        					 
    u16x0 = u16ADC_GetResult() - u16x0;
	
	ACCEL_SELF_TEST = ACCEL_NORMAL_OPERATION;
	
	if( (u16x0 >= SENSOR_ACCEL_TEST_MINZ) && (u16x0 <= SENSOR_ACCEL_TEST_MAXZ ))
	{
		return SENSOR_ACCEL_TEST_OK;
	}
	else
	{
		return SENSOR_ACCEL_TEST_FAIL;
	}
	
}

void vfnSensor_ADC_Config (void)
{
    vfnADC_ResolutionSelect (ADC_RESOLUTION_10BIT);
    vfnADC_SetSampleTime (ADC_LONG_SAMPLE_TIME);
    vfnADC_LowPowerMode ();
    vfnADC_ConversionMode (ADC_SINGLE_CONVERSION);
    vfnADC_ClockDivideSelect (ADC_CLK_DIVIDER_4); // Adc runs at 2 MHz
    
    vfnADC_PinEnable (SENSOR_ACCEL_X_CH);
    vfnADC_PinEnable (SENSOR_ACCEL_Y_CH);
    vfnADC_PinEnable (SENSOR_ACCEL_Z_CH);
    vfnADC_PinEnable (SENSOR_SLIDER_CH);
    vfnADC_PinEnable (SENSOR_BATTERY_CH);
    
    // Turn on ADC module
    vfnADC_UseBusClock ();
}

uint8 u8Sensor_GetAccelX (void)
{
    uint16 u16sensor_data;
    uint8 u8sensor_data;
    
    // Select corresponding ADC channel
    vfnADC_ChannelSelect (SENSOR_ACCEL_X_CH);
    
    // Wait for conversion to complete
    while(!u8ADC_CheckCCF());
    
    // Get the result, adjust it to 8 bit and return the filtered value
        					 
    u16sensor_data = (uint16)((long)u16ADC_GetResult() - (long)i8adc_xoffset_calibration);
    
    if( (u16sensor_data < FREE_FALL_MAX) && (u16sensor_data > FREE_FALL_MIN))
    {
    	u8FreeFall |= SENSOR_FREE_FALL_X;
    }	
                                                                        
    if (u16sensor_data >= u16adc_x_10bit_max)
    {                                                                   
        u8sensor_data = ADC_8_BIT_MAX;
    }                                                                  
    else if (u16sensor_data <= u16adc_x_10bit_min)
    {                                                                  
        u8sensor_data = ADC_8_BIT_MIN;
    }                                                                   
    else                                                                
    {                                                                   
        u8sensor_data = (uint8)(u16sensor_data - ADC_10_2_8_BITS_CONVERSION);     
    }
    
    
    #if (SENSOR_ACCEL_X_FILTER == FILTER_ENABLED)
    
        return u8FilterADCX(u8sensor_data);
    
    #else
    
        return u8sensor_data;
    
    #endif    
}

uint8 u8Sensor_GetAccelY (void)
{
    uint16 u16sensor_data;
    uint8 u8sensor_data;
    
    // Select corresponding ADC channel
    vfnADC_ChannelSelect (SENSOR_ACCEL_Y_CH);
    
    // Wait for conversion to complete
    while(!u8ADC_CheckCCF());
    
    // Get the result, adjust it to 8 bit and return the filtered value
        					 
    u16sensor_data = (uint16)((long)u16ADC_GetResult() - (long)i8adc_yoffset_calibration);
    
    if( (u16sensor_data < FREE_FALL_MAX) && (u16sensor_data > FREE_FALL_MIN))
    {
    	u8FreeFall |= SENSOR_FREE_FALL_Y;
    }
                                                                        
    if (u16sensor_data >= u16adc_y_10bit_max)
    {                                                                   
        u8sensor_data = ADC_8_BIT_MAX;
    }                                                                  
    else if (u16sensor_data <= u16adc_y_10bit_min)
    {                                                                  
        u8sensor_data = ADC_8_BIT_MIN;
    }                                                                   
    else                                                                
    {                                                                   
        u8sensor_data = (uint8)(u16sensor_data - ADC_10_2_8_BITS_CONVERSION);     
    }
    
    
    #if (SENSOR_ACCEL_Y_FILTER == FILTER_ENABLED)
    
        return u8FilterADCY(u8sensor_data);
    
    #else
    
        return u8sensor_data;
    
    #endif    
}

uint8 u8Sensor_GetAccelZ (void)
{
    uint16 u16sensor_data;
    uint8 u8sensor_data;
    
    // Select corresponding ADC channel
    vfnADC_ChannelSelect (SENSOR_ACCEL_Z_CH);
    
    // Wait for conversion to complete
    while(!u8ADC_CheckCCF());
    
    // Get the result, adjust it to 8 bit and return the filtered value
        					 
    u16sensor_data = (uint16)((long)u16ADC_GetResult() - (long)i8adc_zoffset_calibration);
    
    if( (u16sensor_data < FREE_FALL_MAX) && (u16sensor_data > FREE_FALL_MIN))
    {
    	u8FreeFall |= SENSOR_FREE_FALL_Z;
    }
                                                                        
    u8sensor_data = (uint8)((u16sensor_data - ADC_10_2_8_BITS_CONVERSION)>>1);     
    
    
    #if (SENSOR_ACCEL_Z_FILTER == FILTER_ENABLED)
    
        return u8FilterADCZ(u8sensor_data);
    
    #else
    
        return u8sensor_data;
    
    #endif    
}

uint8 u8Sensor_GetBatteryLevel (void)
{
    uint8 u8sensor_data;
    
    // Select corresponding ADC channel
    vfnADC_ChannelSelect (SENSOR_BATTERY_CH);

    // Wait for conversion to complete
    while(!u8ADC_CheckCCF());
    
    u8sensor_data = (uint8)(u16ADC_GetResult() >> 2);
    
    #if SENSOR_BATTERY_FILTER == FILTER_ENABLED
    
        // Call the filtering function and return the value
    
    #else
    
        return u8sensor_data;
    
    #endif
}



uint8 u8Sensor_GetSpeed (void)
{
    uint16 u16sensor_data;
    
    // Select corresponding ADC channel
    vfnADC_ChannelSelect (SENSOR_SLIDER_CH);

    // Wait for conversion to complete
    while(!u8ADC_CheckCCF());
    
    u16sensor_data = u16ADC_GetResult() >> 1;
    
    #if SENSOR_SLIDER_FILTER == FILTER_ENABLED
    
        // Call the filtering function and return the value
    
    #else
		if(u16sensor_data & 0x0F00)
			return 0xFF;
		else
			return (uint8)u16sensor_data;
    
    #endif
}

/* This function is not being used for the time being

uint8 u8Sensor_GetLightLevel (void)
{
    uint8 u8sensor_data;
    
    // Select corresponding ADC channel
    vfnADC_ChannelSelect (SENSOR_LIGHT_CH);

    // Wait for conversion to complete
    while(!u8ADC_CheckCCF());
    
    u8sensor_data = u8ADC_GetResult();
    
    #if SENSOR_LIGHT_FILTER == FILTER_ENABLED
    
        // Call the filtering function and return the value
    
    #else
    
        return u8sensor_data;
    
    #endif
}
*/

void vfnSensor_LoadCalibrationValues (void)
{
    u16adc_x_10bit_max = u16_ADCX_10b_zero_offset + ADC_10_BIT_MAX;
    u16adc_x_10bit_min = u16_ADCX_10b_zero_offset + ADC_10_BIT_MIN;
 
    u16adc_y_10bit_max = u16_ADCY_10b_zero_offset + ADC_10_BIT_MAX;
    u16adc_y_10bit_min = u16_ADCY_10b_zero_offset + ADC_10_BIT_MIN;
 
    u16adc_z_10bit_max = u16_ADCZ_10b_zero_offset + ADC_10_BIT_MAX;
    u16adc_z_10bit_min = u16_ADCZ_10b_zero_offset + ADC_10_BIT_MIN;
    
    i8adc_xoffset_calibration = (int8)(u16_ADCX_10b_zero_offset - ADC_10_BIT_ZERO_OFFSET);
    i8adc_yoffset_calibration = (int8)(u16_ADCY_10b_zero_offset - ADC_10_BIT_ZERO_OFFSET);
    i8adc_zoffset_calibration = (int8)(u16_ADCZ_10b_zero_offset - ADC_10_BIT_ZERO_OFFSET);
}











